#include "stdafx.h"
#include "Properties.h"



namespace woe
{

	Properties::Properties(const string& file_name /* = */ )
	{
		if (!file_name.empty())
		{
			init(file_name);
		}
	}

	bool Properties::init(const string& file_name)
	{
		std::ifstream fprop;

		fprop.open(file_name.c_str() );

		if( !fprop.good() )
		{
			return false;
		}

		string line;
		std::map<string, string> key_values;

		while( fprop.good() && !fprop.eof())
		{
			getline( fprop, line );
			if( add_line( line) )
			{
			}
		}
		return true;
	}

	bool Properties::add_line( const string & line)
	{
		// skip comments '#' and empty lines.
		if (line.empty() || '#' == line[0])
		{
			return false;
		}

		size_t pos = line.find_first_not_of((" \t" )) ;

		if(string::npos == pos)
		{
			return false;
		}

		if('#' == line[pos]) 
			return false;

		size_t pos_end = line.find_first_of((" \t="));

		if (pos_end<=pos || pos_end==string::npos)
		{
			return false;
		}

		string key = line.substr(pos, pos_end-pos);

		if (line[pos_end]==('='))
		{
			pos = pos_end+1;
		}
		else
		{
			pos = line.find_first_of(('='), pos_end);
			if (pos==string::npos)
			{
				return false;
			}
			pos++;
		}

		pos = line.find_first_not_of((" \t="), pos);

		pos_end = line.find_first_of((" \t\n\r=") , pos);

		string value;

		if( string::npos == pos_end )
		{
			value = line.substr(pos);
		}
		else
		{
			value = line.substr(pos, pos_end-pos);
		}

		if (!value.empty())
		{
			pairs_[key] = value;
			return true;
		}
		else
		{
			return false;
		}
	}

#ifdef UNICODE
#define		atoint	_wtoi
#else
#define		atoint	atoi
#endif

	bool Properties::parse(const string& key, string& value)
	{
		Key2Value::iterator it = pairs_.find(key);
		if (it==pairs_.end())
		{
			return false;
		}
		else
		{
			value = it->second;
			return true;
		}
	}

	bool Properties::parse(const string& key, short& value)
	{
		Key2Value::iterator it = pairs_.find(key);
		if (it==pairs_.end())
		{
			return false;
		}
		else
		{
			if (key != it->second &&
				parse(it->second, value))
			{
				it->second = pairs_[it->second];
				return true;
			}
			else
			{
#ifdef _WIN32
				value = (short)atoint(it->second.c_str());
#else
				value =(short)atoi(ws2s(it->second).c_str());
#endif
				return true;
			}
		}
	}

	bool Properties::parse(const string& key, int& value)
	{
		Key2Value::iterator it = pairs_.find(key);
		if (it==pairs_.end())
		{
			return false;
		}
		else
		{
			if (key != it->second &&
				parse(it->second, value))
			{
				it->second = pairs_[it->second];
				return true;
			}
			else
			{
#ifdef _WIN32
				value = atoint(it->second.c_str());
#else
				value = atoi(ws2s(it->second).c_str());
#endif
				return true;
			}
		}
	}

	bool Properties::parse(const string& key, bool& value)
	{
		int value_i;
		if (parse(key, value_i))
		{
			value = (value_i!=0);
			return true;
		}
		else
		{
			return false;
		}
	}
}